/**
 * HTTP请求服务
 * 封装微信小程序网络请求API
 */

const app = getApp();

/**
 * 基础请求方法
 * @param {Object} options 请求配置
 * @returns {Promise} Promise对象
 */
const request = (options) => {
  // 获取全局配置
  const baseUrl = app.globalData.apiBaseUrl || '';
  const token = app.globalData.token || '';
  
  // 合并请求头
  const header = {
    'Content-Type': 'application/json',
    ...options.header
  };
  
  // 如果有token，添加到请求头
  if (token) {
    header['Authorization'] = `Bearer ${token}`;
  }
  
  return new Promise((resolve, reject) => {
    wx.request({
      url: baseUrl + options.url,
      data: options.data,
      method: options.method || 'GET',
      header: header,
      success: (res) => {
        // 请求成功，但需要判断业务状态码
        if (res.statusCode >= 200 && res.statusCode < 300) {
          // 业务状态判断（根据后端接口规范调整）
          if (res.data.code === 0 || res.data.code === 200) {
            resolve(res.data.data);
          } else {
            // 业务错误
            const error = {
              code: res.data.code,
              message: res.data.message || '请求失败',
              data: res.data
            };
            
            // 处理特定错误码
            handleErrorCode(error.code, error.message);
            
            reject(error);
          }
        } else {
          // HTTP错误
          const error = {
            code: res.statusCode,
            message: '网络请求错误',
            data: res.data
          };
          
          // 处理HTTP错误码
          handleHttpError(res.statusCode);
          
          reject(error);
        }
      },
      fail: (err) => {
        // 网络请求失败
        const error = {
          code: -1,
          message: '网络连接失败，请检查网络设置',
          data: err
        };
        
        wx.showToast({
          title: error.message,
          icon: 'none'
        });
        
        reject(error);
      }
    });
  });
};

/**
 * 处理业务错误码
 * @param {Number} code 错误码
 * @param {String} message 错误信息
 */
const handleErrorCode = (code, message) => {
  // 根据业务错误码进行相应处理
  switch (code) {
    case 401: // 未授权
      wx.showToast({
        title: '登录已过期，请重新登录',
        icon: 'none'
      });
      
      // 清除登录状态，跳转到登录页
      setTimeout(() => {
        app.logout();
      }, 1500);
      break;
      
    case 403: // 禁止访问
      wx.showToast({
        title: '您没有权限进行此操作',
        icon: 'none'
      });
      break;
      
    case 4001: // 已绑定伴侣
      wx.showToast({
        title: '您已绑定伴侣',
        icon: 'none'
      });
      break;
      
    case 4002: // 绑定码过期
      wx.showToast({
        title: '绑定码已过期',
        icon: 'none'
      });
      break;
      
    case 4003: // 绑定码无效
      wx.showToast({
        title: '绑定码无效',
        icon: 'none'
      });
      break;
      
    default:
      // 默认错误提示
      wx.showToast({
        title: message || '操作失败',
        icon: 'none'
      });
  }
};

/**
 * 处理HTTP错误
 * @param {Number} statusCode HTTP状态码
 */
const handleHttpError = (statusCode) => {
  let message = '网络请求错误';
  
  switch (statusCode) {
    case 401:
      message = '登录已过期，请重新登录';
      
      // 清除登录状态，跳转到登录页
      setTimeout(() => {
        app.logout();
      }, 1500);
      break;
      
    case 403:
      message = '您没有权限进行此操作';
      break;
      
    case 404:
      message = '请求的资源不存在';
      break;
      
    case 500:
      message = '服务器错误，请稍后再试';
      break;
      
    case 502:
      message = '网关错误，请稍后再试';
      break;
      
    case 503:
      message = '服务不可用，请稍后再试';
      break;
  }
  
  wx.showToast({
    title: message,
    icon: 'none'
  });
};

/**
 * GET请求
 * @param {String} url 请求地址
 * @param {Object} data 请求参数
 * @param {Object} header 请求头
 * @returns {Promise} Promise对象
 */
const get = (url, data = {}, header = {}) => {
  return request({
    url,
    data,
    method: 'GET',
    header
  });
};

/**
 * POST请求
 * @param {String} url 请求地址
 * @param {Object} data 请求参数
 * @param {Object} header 请求头
 * @returns {Promise} Promise对象
 */
const post = (url, data = {}, header = {}) => {
  return request({
    url,
    data,
    method: 'POST',
    header
  });
};

/**
 * PUT请求
 * @param {String} url 请求地址
 * @param {Object} data 请求参数
 * @param {Object} header 请求头
 * @returns {Promise} Promise对象
 */
const put = (url, data = {}, header = {}) => {
  return request({
    url,
    data,
    method: 'PUT',
    header
  });
};

/**
 * DELETE请求
 * @param {String} url 请求地址
 * @param {Object} data 请求参数
 * @param {Object} header 请求头
 * @returns {Promise} Promise对象
 */
const del = (url, data = {}, header = {}) => {
  return request({
    url,
    data,
    method: 'DELETE',
    header
  });
};

/**
 * 上传文件
 * @param {String} url 上传地址
 * @param {String} filePath 文件路径
 * @param {String} name 文件对应的key
 * @param {Object} formData 附加的表单数据
 * @param {Object} header 请求头
 * @returns {Promise} Promise对象
 */
const uploadFile = (url, filePath, name = 'file', formData = {}, header = {}) => {
  // 获取全局配置
  const baseUrl = app.globalData.apiBaseUrl || '';
  const token = app.globalData.token || '';
  
  // 合并请求头
  const headerObj = {
    ...header
  };
  
  // 如果有token，添加到请求头
  if (token) {
    headerObj['Authorization'] = `Bearer ${token}`;
  }
  
  return new Promise((resolve, reject) => {
    wx.uploadFile({
      url: baseUrl + url,
      filePath: filePath,
      name: name,
      formData: formData,
      header: headerObj,
      success: (res) => {
        // 上传成功，但需要判断业务状态码
        if (res.statusCode >= 200 && res.statusCode < 300) {
          // 将返回的JSON字符串转为对象
          let data;
          try {
            data = JSON.parse(res.data);
          } catch (e) {
            data = res.data;
          }
          
          // 业务状态判断（根据后端接口规范调整）
          if (data.code === 0 || data.code === 200) {
            resolve(data.data);
          } else {
            // 业务错误
            const error = {
              code: data.code,
              message: data.message || '上传失败',
              data: data
            };
            
            // 处理特定错误码
            handleErrorCode(error.code, error.message);
            
            reject(error);
          }
        } else {
          // HTTP错误
          const error = {
            code: res.statusCode,
            message: '网络请求错误',
            data: res.data
          };
          
          // 处理HTTP错误码
          handleHttpError(res.statusCode);
          
          reject(error);
        }
      },
      fail: (err) => {
        // 上传失败
        const error = {
          code: -1,
          message: '文件上传失败，请检查网络设置',
          data: err
        };
        
        wx.showToast({
          title: error.message,
          icon: 'none'
        });
        
        reject(error);
      }
    });
  });
};

module.exports = {
  request,
  get,
  post,
  put,
  del,
  uploadFile
};